package com.ruoyi.common.utils.http;

import com.alibaba.fastjson2.JSONObject;
import okhttp3.*;
import okhttp3.logging.HttpLoggingInterceptor;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class OkHttpUtils {
    private OkHttpClient client;
    private Request.Builder builder;

    public static OkHttpUtils getInstance() {
        return new OkHttpUtils();
    }

    public OkHttpUtils init() {
        HttpLoggingInterceptor interceptorLog = new HttpLoggingInterceptor(new OkHttpLogger());
        interceptorLog.setLevel(HttpLoggingInterceptor.Level.BASIC);
        client = new OkHttpClient.Builder()
                .connectTimeout(120, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .addInterceptor(interceptorLog)
                .build();
        builder = new Request.Builder();
        return this;
    }

    public OkHttpUtils init(String proxyIp,int proxyPort) {
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIp, proxyPort));
        HttpLoggingInterceptor interceptorLog = new HttpLoggingInterceptor(new OkHttpLogger());
        interceptorLog.setLevel(HttpLoggingInterceptor.Level.BODY);
        client = new OkHttpClient.Builder()
                .connectTimeout(120, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .proxy(proxy)
                .addInterceptor(interceptorLog)
                .build();
        builder = new Request.Builder();
        return this;
    }

    public OkHttpUtils url(String url) {
        builder.url(url);
        return this;
    }

    public OkHttpUtils header(String name, String value) {
        builder.header(name, value);
        return this;
    }



    public OkHttpUtils get() {
        builder.get();
        return this;
    }

    public OkHttpUtils jsonBodyPut(JSONObject body) {
        builder.put(RequestBody.create(
                MediaType.parse("application/json; charset=utf-8"),
                body.toJSONString()));
        return this;
    }

    public OkHttpUtils jsonBodyPost(JSONObject body) {
        builder.post(RequestBody.create(
                MediaType.parse("application/json; charset=utf-8"),
                body.toJSONString()));
        return this;
    }

    //application/x-www-form-urlencoded
    public OkHttpUtils formBodyPost(Map<String, String> body) {
        FormBody.Builder formBuilder = new FormBody.Builder();
        for (String key : body.keySet()) {
            formBuilder.add(key, body.get(key));
        }
        builder.post(formBuilder.build());
        return this;
    }



    public OkHttpUtils formBodyPut(Map<String, String> body) {
        FormBody.Builder formBuilder = new FormBody.Builder();
        for (String key : body.keySet()) {
            formBuilder.add(key, body.get(key));
        }
        builder.put(formBuilder.build());
        return this;
    }



    public OkHttpUtils postFile(JSONObject param,String filePartName, File file) {
//        MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
        MultipartBody.Builder mulPartBuild = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);
        if(param!=null){
            param.keySet().stream().forEach(key->{
                mulPartBuild.addFormDataPart(key,param.get(key).toString());
            });
        }
        mulPartBuild.addFormDataPart(filePartName, file.getName(),
                        RequestBody.create(null, file));
        RequestBody requestBody = mulPartBuild.build();
        builder.post(requestBody);
        return this;
    }


    public void execSync(OnResponse onResponse) {
        client.newCall(builder.build()).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                onResponse.onError(e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    onResponse.onSuccess(response);
                }
            }
        });
    }


    public void exec(OnResponse onResponse){
        try {
            Call call = client.newCall(builder.build());
            Response response = call.execute();
            if(response.isSuccessful()){
                onResponse.onSuccess(response);
            }else {
                onResponse.onError(new Exception("请求异常"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public interface OnResponse {
        void onSuccess(Response response);

        void onError(Exception e);
    }
}
